import axios, {
  AxiosRequestConfig, AxiosResponse, AxiosError
} from 'axios'

const http = axios.create({
  baseURL: '/api',
  withCredentials: true,
  timeout: 10000
})

// request before 处理
function requestBeforeHandle(config: AxiosRequestConfig) {
  Object.assign(config.headers, {
    // TODO 固定写死，失效需手动更新
    // twork.dev
    authorization: 'bearer 78a4307a-2606-43c1-869b-655598bc85df'
  })

  return config
}

// request error 处理
function requestErrorHandle(err: Error) {
  console.error(err.message)

  return Promise.reject(err)
}

// response 数据 处理
function responseDataHandle(res: AxiosResponse) {
  if (res.request.responseType === 'blob') {
    return res.data
  }
  const {
    code, data, msg
  } = res.data
  if (code === 0) { // 请求成功
    return data
  }
  // 请求出错，默认 显示 消息提示
  // TODO 需支持配置关闭提示
  console.error(msg)

  // 请求出错时，返回 全部数据，以便于业务进行其他操作
  return Promise.reject(res.data)
}

// response error 处理
function responseErrorHandle(err: AxiosError) {
  let text

  try {
    if (err.response) {
      // 优先获取 后端返回 data 中 msg
      const { code, msg } = err.response.data
      if (code && msg) {
        text = msg
      } else {
        text = '系统繁忙，请重试...'
      }
    } else {
      throw err
    }
  } catch (e) {
    // TODO 此处可根据 请求错误类型 显示对应提示
    // 例如：无网络连接、请求超时、服务器错误等
    // 根据不同错误类型，和产品确认提示文案
    const tips = err.code === 'ECONNABORTED' ? '请求超时' : '系统繁忙'
    text = `${tips}，请重试...`
  }

  console.error(text)

  return Promise.reject(err)
}

http.interceptors.request.use(
  requestBeforeHandle,
  requestErrorHandle
)
http.interceptors.response.use(
  responseDataHandle,
  responseErrorHandle
)

export default http
